import { reactive } from 'vue';

interface IActionOption {
  log?: string;
}

interface IModuleOption {
  name: string;
}

const logs: string[] = [];

export interface Module<T> {
  state: T;
}
/**
 * Action descriptor. It's readonly.
 * @param option
 *  log：Output log text when this action done.
 */
export const Action = ({ log }: IActionOption = {}) =>
  (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {

  descriptor.writable = false;

  // const action = descriptor.value;

  // descriptor.value = function(): any {
  //   // tslint:disable-next-line:no-unused-expression
  //   log && logs.push(log);
  //   return action.apply(this, arguments);
  // };

  return descriptor;
};


/**
 * Module descriptor.
 * 利用vue3中的reactive()包装obj.state，使其具有响应式。
 * @param option 
 *  name: name of Module. 
 */
export const YubiModule = ({ name }: IModuleOption) =>
  (target: any): any => {
    target.prototype.name = name;

    target = new Proxy(target, {
      construct: (target: any, argArray: any[], newTarget: any) => {
        const obj = new target(...argArray);
        obj.state = reactive(obj.state);
        return obj;
      }
    })
    return target;
  };


export const getLog = (): string[] => {
  return logs;
};
